home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / Snippets / QuickDraw / Imageer 1.0.0d3 / source / fileCache.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-02-16  |  12.7 KB  |  480 lines  |  [TEXT/MPS ]

  1. /****************************************************/
  2. /*                                                    */
  3. /*    File:        fileCache.c                            */
  4. /*                                                    */
  5. /*    Program:    Imageer                                */
  6. /*                                                    */
  7. /*    By:            Jason Hodges-Harris                    */
  8. /*                                                    */
  9. /*    Created:    12/01/95  00:00:00 AM                */
  10. /*                                                    */
  11. /*    Version:    1.0.0d3                                */
  12. /*                                                    */
  13. /*    Copyright:    © 1995-96 Apple Computer, Inc.,        */ 
  14. /*                    all rights reserved.            */        
  15. /*                                                    */
  16. /****************************************************/
  17.  
  18.  
  19. /**** Macintosh Toolbox Headers *****/
  20.  
  21. #ifndef __FILES__
  22. #include <Files.h>
  23. #endif
  24.  
  25. #ifndef __FOLDERS__
  26. #include <Folders.h>
  27. #endif
  28.  
  29. #ifndef __SCRIPT__
  30. #include <Script.h>
  31. #endif
  32.  
  33. #ifndef __STANDARDFILE__
  34. #include <StandardFile.h>
  35. #endif
  36.  
  37. #ifndef __STRING__
  38. #include <string.h>
  39. #endif
  40.  
  41. #ifndef __STRINGS__
  42. #include <Strings.h>
  43. #endif
  44.  
  45. #ifndef __TEXTUTILS__
  46. #include <TextUtils.h>
  47. #endif
  48.  
  49. #ifndef __TYPES__
  50. #include <Types.h>
  51. #endif
  52.  
  53.  
  54. /****   Application headers and prototypes   ****/
  55.  
  56.  
  57. #ifndef __IMAGEERAPPHEADER__
  58. #include "Imageer.app.h"
  59. #endif
  60.  
  61. #ifndef __IMAGEERPROTOSHEADER__
  62. #include "Imageer.protos.h"
  63. #endif
  64.  
  65.  
  66. /****    Global variables    ****/
  67.  
  68. extern long     gTempFolderDirID,
  69.                 gTempFileCount;
  70. extern short     gTempFolderVolRef;
  71.  
  72.  
  73. /****    Test to find if temporary folder exists    ****/
  74.  
  75. //    function tests for existence of the Temporary Folder inside the System Folder
  76. //    and creates folder if not present
  77.  
  78. #pragma segment imageCache
  79. OSErr    FindTempFolder(void)
  80. {
  81.     OSErr        error = noErr;
  82.     Boolean        tempExists = false;
  83.  
  84.     error = FindFolder(kOnSystemDisk, kTemporaryFolderType,
  85.                        kCreateFolder,&gTempFolderVolRef,
  86.                        &gTempFolderDirID);
  87.     if (error)
  88.         DisplayAlert (rGenWarning,rFileIOMessages,iCreateTempFldrErr);    
  89.     return error;
  90. }
  91.  
  92.  
  93. /****    Remove image docs temporary files    ****/
  94.  
  95. // Delete temp file(s) specified in boolean input parameters
  96. // used to hold Color QD cache information for undo/redo
  97.  
  98. #pragma segment imageCache
  99. OSErr    RemoveTempFile(ImageDocHndl theDocHndl, Boolean delUndoFile, Boolean delRedoFile)
  100. {
  101.     OSErr        error = noErr;
  102.     
  103.     HLock((Handle)theDocHndl);
  104.     if (delUndoFile)
  105.     {
  106.         error = FSpDelete(&(*theDocHndl)->theTempUndoFileSpec);
  107.         (*theDocHndl)->hasUndoTemp = false;
  108.     }
  109.     if (delRedoFile)
  110.     {
  111.         error |= FSpDelete(&(*theDocHndl)->theTempRedoFileSpec);
  112.         (*theDocHndl)->hasRedoTemp = false;
  113.     }
  114.     HUnlock((Handle)theDocHndl);
  115.     error = noErr;     // currently ignore error checking 
  116.     if (error)
  117.         DisplayAlert (rGenWarning,rFileIOMessages,iDeleteTempFileErr);
  118.     return error;
  119. }
  120.  
  121.  
  122. /****    Save temporary Undo file    ****/
  123.  
  124. // save cache file information from current image window prior
  125. // to image manipulation after removing previous obselete temporary file(s).
  126.  
  127. #pragma segment imageCache
  128. OSErr    SaveTempImageFile(ImageDocHndl theDocHndl, short tempFileOp)
  129. {
  130.     Str255            theMenuString,
  131.                     theResString;
  132.     OSErr            error = noErr;
  133.     Boolean            isRedoTempFile = false;
  134.     
  135.     (*theDocHndl)->theLastAction = tempFileOp;
  136.     GetMenuItemText(GetMHandle(mEdit),iUndo,theMenuString);    
  137.     GetIndString (theResString,rMenuItems,iOpRedo);
  138.     if (EqualString(theMenuString,theResString,true,true))
  139.         isRedoTempFile = true;
  140.     if (!isRedoTempFile)
  141.         RemoveTempFile(theDocHndl, true, true);
  142.     else
  143.         RemoveTempFile(theDocHndl, false, true);
  144.     switch (tempFileOp)
  145.     {
  146.         case kPixMapOp:
  147.             error = SavePixMaptoTemp(theDocHndl, isRedoTempFile);
  148.             if (error)
  149.             {
  150.                 (*theDocHndl)->theUndoState = kCannotUndo;
  151.                 DebugStr("\pError saving image PixMap to temp file.");
  152.             }
  153.         break;
  154.         case kColorTableOp:
  155.             error = SaveCTabtoTemp(theDocHndl, isRedoTempFile);
  156.             if (error)
  157.             {
  158.                 (*theDocHndl)->theUndoState = kCannotUndo;
  159.                 DebugStr("\pError saving image colorTable to temp file.");
  160.             }
  161.         break;
  162.         case kGXTransformOp:
  163.         break;
  164.     }
  165.     SetUndoItemText((*theDocHndl)->theUndoState);
  166.     return error;
  167. }
  168.  
  169.  
  170. /****    Load temporary file    ****/
  171.  
  172. // Retrieve stored temporary file information and use to revert offscreen image to old state
  173.  
  174. #pragma segment imageCache
  175. OSErr    LoadTempImageFile(ImageDocHndl theDocHndl)
  176. {
  177.     Str255            theMenuString,
  178.                     theResString;
  179.     OSErr            error = noErr;
  180.     short            tempFileOpType = (*theDocHndl)->theLastAction;
  181.     Boolean            isRedoTempFile = false;
  182.     
  183.     (*theDocHndl)->theLastAction = tempFileOpType;
  184.     GetMenuItemText(GetMHandle(mEdit),iUndo,theMenuString);    
  185.     GetIndString (theResString,rMenuItems,iOpRedo);
  186.     if (EqualString(theMenuString,theResString,true,true))
  187.         isRedoTempFile = true;
  188.     switch (tempFileOpType)
  189.     {
  190.         case kPixMapOp:
  191.             if (!isRedoTempFile)
  192.                 error = SavePixMaptoTemp(theDocHndl, true);
  193.             error |= LoadTemptoPixMap(theDocHndl, isRedoTempFile);
  194.             if (error)
  195.                 DebugStr("\pError loading image PixMap from temp file.");
  196.         break;
  197.         case kColorTableOp:
  198.             if (!isRedoTempFile)
  199.                 error = SaveCTabtoTemp(theDocHndl, true);
  200.             error |= LoadTemptoCTab(theDocHndl, isRedoTempFile);
  201.             if (error)
  202.                 DebugStr("\pError loading image color table from temp file.");
  203.         break;
  204.         case kGXTransformOp:
  205.         break;
  206.     }
  207.     if (isRedoTempFile)
  208.         (*theDocHndl)->theUndoState = kCanUndo;
  209.     SetUndoItemText((*theDocHndl)->theUndoState);
  210.     return error;
  211. }
  212.  
  213.  
  214. /****    Save Pixmap Data to temporary file    ****/
  215.  
  216. // Store locked down offscreen GWorld Pixmap in temp file for undo/redo operation
  217.  
  218. #pragma segment imageCache
  219. OSErr    SavePixMaptoTemp(ImageDocHndl theDocHndl, Boolean isRedoFile)
  220. {
  221.     PixMapHandle    thePixMapHndl = nil;
  222.     Ptr                pixMapData;
  223.     long            width,
  224.                     height,
  225.                     fileSize,
  226.                     diskSpace,
  227.                     count;
  228.     Str63            tempFileName,
  229.                     fileNumStr;
  230.     short            fileRefNum,
  231.                     theVolRef;
  232.     OSErr            error = noErr;
  233.  
  234.     thePixMapHndl = GetGWorldPixMap((**theDocHndl).theImageWorld);
  235.     if (PixMap32Bit(thePixMapHndl))
  236.         SaveSetMMUMode(true);
  237.     if (!LockPixels(thePixMapHndl))
  238.         error = kFailedLockPixels;
  239.     if (!error)
  240.     {
  241.         width = (**thePixMapHndl).rowBytes & 0x3FFF;
  242.         height = (**theDocHndl).theImageYSize;
  243.         fileSize = width*height;
  244.         error = GetVInfo(gTempFolderVolRef, 0,&theVolRef, &diskSpace);
  245.         if (error)
  246.         {
  247.             DebugStr("\pCouldn't get information for Temporory folder volume.");
  248.             return kDefaultAppError;
  249.         }
  250.         // Test for adequate space on hard disk to save file information.
  251.         // Display warning dialog and return without saving data if disk is full
  252.         if (fileSize > diskSpace)
  253.         {
  254.             DisplayAlert (rGenWarning,rFileIOMessages,iDiskFullErr);
  255.             return kDefaultAppError;
  256.         }
  257.         pixMapData = GetPixBaseAddr(thePixMapHndl);
  258.         if (isRedoFile)
  259.         {
  260.             (*theDocHndl)->theTempRedoFileSpec.vRefNum = gTempFolderVolRef;
  261.             (*theDocHndl)->theTempRedoFileSpec.parID = gTempFolderDirID;
  262.             (*theDocHndl)->hasRedoTemp = true;
  263.             (*theDocHndl)->theUndoState = kCanRedo;
  264.         }
  265.         else
  266.         {
  267.             (*theDocHndl)->theTempUndoFileSpec.vRefNum = gTempFolderVolRef;
  268.             (*theDocHndl)->theTempUndoFileSpec.parID = gTempFolderDirID;
  269.             (*theDocHndl)->hasUndoTemp = true;
  270.             (*theDocHndl)->theUndoState = kCanUndo;
  271.         }
  272.         // Create new temporary file name
  273.         // using an incremental number appended to filename to keep unique.
  274.         strcpy((char*)tempFileName,(char*)"\pTempFile");
  275.         NumToString(gTempFileCount,fileNumStr);
  276.         gTempFileCount++;
  277.         p2cstr(tempFileName);
  278.         p2cstr(fileNumStr);
  279.         strcat((char*)tempFileName,(char *)fileNumStr);
  280.         c2pstr((char*)tempFileName);
  281.         // Save undo/redo file after first creating and opening new file.
  282.         if (!isRedoFile)
  283.         {
  284.             strcpy((char*)(*theDocHndl)->theTempUndoFileSpec.name,(char*)tempFileName);
  285.             error = FSpCreate(&(*theDocHndl)->theTempUndoFileSpec,
  286.                                (OSType)AppCreator, 'Imtp', smSystemScript);
  287.             if (!error)
  288.                 error = FSpOpenDF(&(*theDocHndl)->theTempUndoFileSpec,fsRdWrPerm,&fileRefNum);
  289.         }
  290.         else
  291.         {
  292.             strcpy((char*)(*theDocHndl)->theTempRedoFileSpec.name,(char*)tempFileName);
  293.             error = FSpCreate(&(*theDocHndl)->theTempRedoFileSpec,
  294.                                (OSType)AppCreator, 'Imtp', smSystemScript);
  295.             if (!error)
  296.                 error = FSpOpenDF(&(*theDocHndl)->theTempRedoFileSpec,fsRdWrPerm,&fileRefNum);
  297.         }
  298.         if (!error)
  299.         {
  300.             for (count = 0;count < height;count++)
  301.             {
  302.                 error = FSWrite(fileRefNum,&width,pixMapData);
  303.                 if (error)
  304.                     DebugStr("\pError Writing Pixmap to Temp File.");
  305.                 pixMapData+=width;
  306.             }
  307.             error = FSClose(fileRefNum);
  308.         }
  309.         UnlockPixels(thePixMapHndl);
  310.     }
  311.     SaveSetMMUMode(false);
  312.     return error;
  313. }
  314.  
  315.  
  316. /****    Load Pixmap Data from temp file    ****/
  317.  
  318. // Retrieve temporary file. Locking down the Offscreen Pixmap,
  319. // before reading in the data directly.
  320.  
  321. #pragma segment imageCache
  322. OSErr    LoadTemptoPixMap(ImageDocHndl theDocHndl, Boolean isRedoFile)
  323. {
  324.     PixMapHandle    thePixMapHndl = nil;
  325.     Ptr                pixMapData;
  326.     long            width,
  327.                     height,
  328.                     count;
  329.     short            fileRefNum;
  330.     OSErr            error = noErr;
  331.  
  332.     thePixMapHndl = GetGWorldPixMap((**theDocHndl).theImageWorld);
  333.     if (PixMap32Bit(thePixMapHndl))
  334.         SaveSetMMUMode(true);
  335.     if (!LockPixels(thePixMapHndl))
  336.         error = kFailedLockPixels;
  337.     if (!error)
  338.     {
  339.         width = (**thePixMapHndl).rowBytes & 0x3FFF;
  340.         height = (**theDocHndl).theImageYSize;
  341.         pixMapData = GetPixBaseAddr(thePixMapHndl);    // base addr of GWorld
  342.         if (isRedoFile)
  343.             error = FSpOpenDF(&(*theDocHndl)->theTempRedoFileSpec,fsRdWrPerm,&fileRefNum);
  344.         else
  345.             error = FSpOpenDF(&(*theDocHndl)->theTempUndoFileSpec,fsRdWrPerm,&fileRefNum);
  346.         if (!error)
  347.         {
  348.             for (count = 0;count < height;count++)
  349.             {
  350.                 FSRead(fileRefNum,&width,pixMapData);
  351.                 pixMapData+=width;
  352.             }
  353.             error = FSClose(fileRefNum);
  354.         }
  355.         UnlockPixels(thePixMapHndl);
  356.     }
  357.     SaveSetMMUMode(false);
  358.     return error;
  359. }
  360.  
  361.  
  362. /****    Save Color QuickDraw color table to temp file    ****/
  363.  
  364. // For indexed Color QuickDraw images, the color table
  365. // information of the offscreen copy of the image is saved. 
  366. // The Color Table's handle is locked down, size determined,
  367. // a new file created and the contents written out
  368. // with a unique name if no error is reported.
  369.  
  370. #pragma segment imageCache
  371. OSErr    SaveCTabtoTemp(ImageDocHndl theDocHndl, Boolean isRedoFile)
  372. {
  373.     CTabHandle        cTabHndl;
  374.     long            fileSize,
  375.                     diskSpace;
  376.     short            fileRefNum,
  377.                     theVolRef;
  378.     OSErr            error = noErr;
  379.     Str63            tempFileName,
  380.                     fileNumStr;
  381.     
  382.     HLock((Handle)(*(*theDocHndl)->theImageWorld->portPixMap)->pmTable);
  383.     cTabHndl = (*(*theDocHndl)->theImageWorld->portPixMap)->pmTable;
  384.     fileSize = GetHandleSize((Handle)cTabHndl);
  385.     error = GetVInfo(gTempFolderVolRef, 0,&theVolRef, &diskSpace);
  386.     if (error)
  387.     {
  388.         DebugStr("\pCouldn't get information for Temporory folder volume.");
  389.         return kDefaultAppError;
  390.     }
  391.     if (fileSize > diskSpace)
  392.     {
  393.         DisplayAlert (rGenWarning,rFileIOMessages,iDiskFullErr);
  394.         return kDefaultAppError;
  395.     }
  396.     if (isRedoFile)
  397.     {
  398.         (*theDocHndl)->theTempRedoFileSpec.vRefNum = gTempFolderVolRef;
  399.         (*theDocHndl)->theTempRedoFileSpec.parID = gTempFolderDirID;
  400.         (*theDocHndl)->hasRedoTemp = true;
  401.         (*theDocHndl)->theUndoState = kCanRedo;
  402.     }
  403.     else
  404.     {
  405.         (*theDocHndl)->theTempUndoFileSpec.vRefNum = gTempFolderVolRef;
  406.         (*theDocHndl)->theTempUndoFileSpec.parID = gTempFolderDirID;
  407.         (*theDocHndl)->hasUndoTemp = true;
  408.         (*theDocHndl)->theUndoState = kCanUndo;
  409.     }
  410.     strcpy((char*)tempFileName,(char*)"\pTempFile");
  411.     NumToString(gTempFileCount,fileNumStr);
  412.     gTempFileCount++;
  413.     p2cstr(tempFileName);
  414.     p2cstr(fileNumStr);
  415.     strcat((char*)tempFileName,(char *)fileNumStr);
  416.     c2pstr((char*)tempFileName);
  417.     if (isRedoFile)
  418.     {
  419.         strcpy((char*)(*theDocHndl)->theTempRedoFileSpec.name,(char*)tempFileName);
  420.         error = FSpCreate(&(*theDocHndl)->theTempRedoFileSpec,
  421.                            (OSType)AppCreator, 'Imtp', smSystemScript);
  422.         if (!error)
  423.             error = FSpOpenDF(&(*theDocHndl)->theTempRedoFileSpec,fsRdWrPerm,&fileRefNum);
  424.         if (!error)
  425.         {
  426.             FSWrite(fileRefNum,&fileSize,(*cTabHndl));
  427.             error = FSClose(fileRefNum);
  428.         }
  429.     }
  430.     else
  431.     {
  432.         strcpy((char*)(*theDocHndl)->theTempUndoFileSpec.name,(char*)tempFileName);
  433.         error = FSpCreate(&(*theDocHndl)->theTempUndoFileSpec,
  434.                            (OSType)AppCreator, 'Imtp', smSystemScript);
  435.         if (!error)
  436.             error = FSpOpenDF(&(*theDocHndl)->theTempUndoFileSpec,fsRdWrPerm,&fileRefNum);
  437.         if (!error)
  438.         {
  439.             error = FSWrite(fileRefNum,&fileSize,*cTabHndl);
  440.             if (error)
  441.                 DebugStr("\pError Writing Pixmap to Temp File.");
  442.             error = FSClose(fileRefNum);
  443.         }
  444.     }
  445.     HUnlock((Handle)cTabHndl);
  446.     return error;
  447. }
  448.  
  449.  
  450. /****    Load temporary file to Color QuickDraw color table    ****/
  451.  
  452. // Load the saved color table cache file into the locked down
  453. // handle of a Color QD image's offscreen ColorTable handle
  454. // structure and force the Color Manager to recalculate the Color Table.
  455.  
  456. #pragma segment imageCache
  457. OSErr    LoadTemptoCTab(ImageDocHndl theDocHndl, Boolean isRedoFile)
  458. {
  459.     CTabHandle        cTabHndl;
  460.     long            fileSize;
  461.     short            fileRefNum;
  462.     OSErr            error = noErr;
  463.     
  464.     HLock((Handle)(*(*theDocHndl)->theImageWorld->portPixMap)->pmTable);
  465.     cTabHndl = (*(*theDocHndl)->theImageWorld->portPixMap)->pmTable;
  466.     fileSize = GetHandleSize((Handle)cTabHndl);
  467.     if (isRedoFile)
  468.         error = FSpOpenDF(&(*theDocHndl)->theTempRedoFileSpec,fsRdWrPerm,&fileRefNum);
  469.     else
  470.         error = FSpOpenDF(&(*theDocHndl)->theTempUndoFileSpec,fsRdWrPerm,&fileRefNum);
  471.     if (!error)
  472.     {
  473.         FSRead(fileRefNum,&fileSize,(*cTabHndl));
  474.         error = FSClose(fileRefNum);
  475.     }
  476.     CTabChanged(cTabHndl);
  477.     HUnlock((Handle)cTabHndl);
  478.     return error;
  479. }
  480.